package org.dfl.core.model;

import java.util.Collection;

import org.dfl.core.data.HistoryDataMapping;
import org.dfl.core.data.PureHistory;
import org.dfl.core.data.Token;
import org.dfl.core.data.connectors.CollectionTypeConnector;
import org.dfl.core.data.connectors.SimpleTypeConnector;
import org.dfl.core.data.connectors.TypeConnector;
import org.dfl.core.model.transitions.Transition;
import org.dfl.messages.Messages;
import org.jdom.Element;



/**
 * input edge to a transition
 * @author Piotr Wlodarczyk
 *
 */
public class TInputEdge extends Edge {
	private String label = "x";

	public String getLabel() {
		return label;
	}

	public void setLabel(String name) {
		this.label = name;
	}

	/**
	 * podaje kolekcje historii, dla ktorych sa dane do pobrania z tego miejsca
	 * 
	 * @param props -
	 *            wlasciwosci danych do sprawdzenia
	 * @return koelekcja historii
	 */
	public Collection<HistoryDataMapping> getFixedHistories() {
		return getPlace().getFixedHistories(this);
	}
	
	/**
	 * zwraca dane dla historii zwroconej przez getFixedHistories
	 * @param hh
	 * @return
	 */
	public Token getToken(PureHistory hh) {
		return getPlace().getToken(hh, this);
	}


	@Override
	public String toString() {
		return "edge from " + getPlace() + " to " //$NON-NLS-1$ //$NON-NLS-2$
				+ (getTransition() != null ? getTransition().getId() : null);
	}

	@Override
	public void connectAction(Place place, Transition transition) throws Exception {
		// inny konektor typow jesli *
		TypeConnector connector = null;
		if(isNested()){
			connector = new CollectionTypeConnector(place.getTypeContainer(), getTypeContainer());
		}else{
			connector = new SimpleTypeConnector(getTypeContainer(), place.getTypeContainer());
		}
		
		// polacz z miejscem
		if(place.addOutputEdge(this,connector)){
			// connect with the transition (type connection inside)
			transition.addInput(this);
		}else{
			//nie powinno sie zdarzyc!
			throw new Exception(Messages.TInputEdge_errorConnectPlace1+place.getId()+Messages.TInputEdge_errorConnectPlace2+getLabel()+Messages.TInputEdge_errorConnectPlace3+transition.getName());
		}
	}
	
	@Override
	public void disconnectAction() {
		if(getPlace()!=null)getPlace().removeOutputEdge(this);
		if(getTransition()!=null)getTransition().removeInput(getLabel());
	}
	
	@Override
	public void load(Element eElem) throws XMLLoaderException {
		super.load(eElem);
		Element tsElem = eElem.getChild("toolspecific"); //$NON-NLS-1$
		if(tsElem != null){
			setLabel(tsElem.getChildText("name")); //$NON-NLS-1$
		}
	}
	
	@Override
	public Element save() {
		Element elem = super.save();
		elem.setAttribute("source",getPlace().getId()); //$NON-NLS-1$
		elem.setAttribute("target",getTransition().getId()); //$NON-NLS-1$
		
		Element tsElem = elem.getChild("toolspecific"); //$NON-NLS-1$
		if(tsElem == null){
			tsElem = new Element("toolspecific"); //$NON-NLS-1$
			tsElem.setAttribute("tool",""); //$NON-NLS-1$ //$NON-NLS-2$
			tsElem.setAttribute("version",""); //$NON-NLS-1$ //$NON-NLS-2$
			elem.addContent(tsElem);
		}
		
		Element nameElem = new Element("name"); //$NON-NLS-1$
		nameElem.setText(getLabel());
		tsElem.addContent(0,nameElem);
		return elem;
	}
}
